import React, { useEffect, useState } from "react";
import { Observable } from 'rxjs';
import { useParams, Navigate } from 'react-router-dom';

interface AuthGuard {
  Component: any;
  redirect?: string;
  canActivate: () => Observable<boolean> | Observable<null> | boolean;
}

export const AuthGuard = (props: AuthGuard) => {
  const [ isPending, isPendingSet ] = useState<boolean>(true);
  const [ auth, authSet ] = useState<boolean>(false);
  const { Component, redirect='/', canActivate } = props;
  useEffect(() => {
    const auth$ = canActivate();
    let authSub: any = null;
    //@ts-ignore
    if(auth$.subscribe){
      //判断传过来的是可监听值还是只是一般的布尔值
      //@ts-ignore
      authSub = auth$.subscribe((r: boolean) => {
        authSet(!!r);
        //如果是可监听的授权值，会有一个等待时间
        isPendingSet(false);
      });
    } else {
      authSet(!!auth$);
      isPendingSet(false);
    };

    return () => {
      authSub && authSub.unsubscribe();
    }
  }, []);

  return isPending ? <span>loading</span> : ( auth ? Component : <Redirect to={ redirect } /> )
};

export const Redirect = (props: {to: string; keys?: string[]}) => {
  const { to, keys = [] } = props;
  const params = useParams();
  let path = to;
  for(let i = 0; i < keys.length; i++){
    const key = keys[i];
    path = to.replace(`:${key}`, params[key]);
  };
  return <Navigate to={path} replace />
};